package servlet;

import entity.Item;
import entity.Order;
import entity.Product;
import entity.User;
import util.JdbcUtil;
import vo.Cart;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

@WebServlet("*.order")
public class OrderServlet extends HttpServlet {


    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        String path = request.getServletPath();

        if ("/create.order".equals(path)) {
            create(request, response);
        }

        if ("/findByUserId.order".equals(path)) {
            findByUserId(request, response);
        }

        if ("/findByOrderId.order".equals(path)) {
            findByOrderId(request, response);
        }
    }

    protected void findByOrderId(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        Integer orderId=Integer.parseInt(request.getParameter("orderId"));

        Order order=null;

        Connection con=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try{

            con=JdbcUtil.getConnection();

            con.setAutoCommit(false);


            String sql=new StringBuffer()
                    .append("select o.id, ")
                    .append("       o.no, ")
                    .append("       u.id, ")
                    .append("       u.username, ")
                    .append("       p.id, ")
                    .append("       p.name, ")
                    .append("       i.id, ")
                    .append("       i.num, ")
                    .append("       i.price, ")
                    .append("       o.price, ")
                    .append("       (select count(1) ")
                    .append("        from t_item item ")
                    .append("        where item.order_id=o.id) \"o.count\" ")
                    .append("from t_order o ")
                    .append("left join t_user u ")
                    .append("    on o.user_id=u.id ")
                    .append("left join t_item i ")
                    .append("    on i.order_id=o.id ")
                    .append("left join t_product p ")
                    .append("    on i.product_id=p.id ")
                    .append("where o.id=? ")
                    .toString();

            ps=con.prepareStatement(sql);

            ps.setInt(1,orderId);

            rs=ps.executeQuery();

            while (rs.next()){
                if (order == null) {
                    order=new Order();
                    order.setId(rs.getInt("o.id"));
                    order.setNo(rs.getString("o.no"));
                    order.setPrice(rs.getDouble("o.price"));
                    order.setCount(rs.getInt("o.count"));

                    User user=new User();
                    user.setId(rs.getInt("u.id"));
                    user.setUsername(rs.getString("u.username"));

                    order.setUser(user);
                }

                if(rs.getInt("i.id")==0){
                    break;
                }

                Product product=new Product();
                product.setId(rs.getInt("p.id"));
                product.setName(rs.getString("p.name"));

                Item item=new Item();
                item.setId(rs.getInt("i.id"));
                item.setNum(rs.getInt("i.num"));
                item.setPrice(rs.getDouble("i.price"));

                item.setProduct(product);

                order.addItem(item);
            }

            con.commit();

        }catch (Exception e){
            e.printStackTrace();
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            JdbcUtil.close(con,ps,rs);
        }

        request.setAttribute("order",order);

        request.getRequestDispatcher("/shop/myOrder.jsp").forward(request,response);

    }


    protected void findByUserId(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        User user= (User) request.getSession().getAttribute("user");


        List<Order> orders=new ArrayList<>();

        Connection con=null;
        PreparedStatement ps=null;
        ResultSet rs=null;

        try{

            con=JdbcUtil.getConnection();

            con.setAutoCommit(false);

            String sql=new StringBuffer()
                    .append("select * ")
                    .append("from t_order ")
                    .append("where user_id=? ")
                    .toString();

            ps=con.prepareStatement(sql);

            ps.setInt(1,user.getId());

            rs=ps.executeQuery();

            while (rs.next()){
                Order order=new Order();
                order.setId(rs.getInt("id"));
                order.setNo(rs.getString("no"));
                order.setCreateDate(rs.getDate("create_date"));

                orders.add(order);
            }

            con.commit();

        }catch (Exception e){
            e.printStackTrace();
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            JdbcUtil.close(con,ps,rs);
        }

        request.setAttribute("orders",orders);

        request.getRequestDispatcher("/shop/myOrders.jsp").forward(request,response);

    }



    protected void create(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession session=request.getSession();

        User user= (User) session.getAttribute("user");

        Cart cart= (Cart) session.getAttribute("cart");


        String no=null;
        Integer orderId=null;

        Connection con=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try{

            con=JdbcUtil.getConnection();

            con.setAutoCommit(false);

            String sql=new StringBuffer()
                    .append("insert into t_order ")
                    .append("    (no,create_date,price,user_id) ")
                    .append("values ")
                    .append("    (?,?,?,?) ")
                    .toString();

            ps=con.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);

            ps.setString(1,no=getNo());
            ps.setDate(2,new java.sql.Date(new Date().getTime()));
            ps.setDouble(3,cart.getPrice());
            ps.setInt(4,user.getId());

            ps.executeUpdate();

            rs=ps.getGeneratedKeys();

            if(rs.next()){
                orderId=rs.getInt(1);
            }

            sql=new StringBuffer()
                    .append("insert into t_item ")
                    .append("    (product_id,num,price,order_id) ")
                    .append("values ")
                    .append("    (?,?,?,?) ")
                    .toString();

            ps=con.prepareStatement(sql);

            List<Item> items=cart.getItems();

            for (Item item : items) {
                ps.setInt(1,item.getProduct().getId());
                ps.setInt(2,item.getNum());
                ps.setDouble(3,item.getPrice());
                ps.setInt(4,orderId);

                ps.addBatch();
            }

            ps.executeBatch();

            con.commit();

        }catch (Exception e){
            e.printStackTrace();
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally {
            JdbcUtil.close(con,ps,rs);
        }


        session.setAttribute("cart",new Cart());

        response.sendRedirect(request.getContextPath()+"/shop/success.jsp?no="+no);
    }

    private synchronized String getNo(){
        Random random=new Random();
        int n=random.nextInt(1000000);

        return new Date().getTime()+String.format("%06d",n);
    }
}